package com.snlab;

import java.io.File;
import java.io.FileNotFoundException;
import java.lang.management.ManagementFactory;
import com.sun.management.OperatingSystemMXBean;
import java.lang.management.ThreadMXBean;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main(String[] args) {
        String router = "atla";
        if (args.length > 0) {
            router = args[0];
            System.out.println(args[0]);
        }
        test(router);
    
    }

    public static void test(String router)
    {
        Runtime runtime = Runtime.getRuntime();
        // System.out.println(runtime.totalMemory() - runtime.freeMemory());
        long start = System.nanoTime();

        APKeep apKeep = new APKeep();
        File inputFile = new File("i2/" + router + "apnotcomp");
        Scanner in = null;
        try {
            in = new Scanner(inputFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        Rule defaultRule = new Rule(0, apKeep.getPort("drop"));
        defaultRule.hit = 1;
        apKeep.insert(defaultRule);

        while (in.hasNextLine()) {
            
            String linestr = in.nextLine();
            String[] tokens = linestr.split(" ");
            String portname = tokens[3].split("\\.")[0];
            
            long ip = Long.parseLong(tokens[1]);
            int prefix = Integer.parseInt(tokens[2]);

            int ipbdd = apKeep.bddEngine.encodeIpv4(ip, prefix);

            Rule rule = new Rule(prefix, apKeep.getPort(portname));
            rule.hit = ipbdd;
            
            apKeep.insert(rule);
       }
       ThreadMXBean mxBean1 = ManagementFactory.getThreadMXBean();
       long cpuTime = mxBean1.getCurrentThreadCpuTime();

       System.out.println("#Rules: " + (apKeep.rules.size() - 1));
       System.out.println("#ECs: " + (apKeep.ppm.size()));


       System.out.println("CPU time(ns): ");
       System.out.println(cpuTime);

       System.out.println("#BDD ops: " + apKeep.bddEngine.cnt);
       System.out.println("#Avg BDD op cpu time(ns): " + (cpuTime / apKeep.bddEngine.cnt));
       
       long totalTime = System.nanoTime() - start;
       System.out.println("Total time(ns): ");
       System.out.println(totalTime);

       System.out.println("#Cores: " + runtime.availableProcessors());
       System.out.println("Avg CPU load: ");
       System.out.println((cpuTime * 1.0 / totalTime / runtime.availableProcessors()));

       apKeep.bddEngine.bdd.gc();
       System.gc();
       System.out.println("Memory(Bytes): ");
       System.out.println(runtime.totalMemory() - runtime.freeMemory());
    }

    
}
